﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using DO.Workflows;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace DAL.Workflows
{
    public class WorkflowDesignDALC
    {
        public static WorkflowDesign GetWorkflow(Guid workflowID)
        {
            string xml = null;
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            IDataReader reader = db.ExecuteReader("WorkflowGet", workflowID);
            if(reader.Read())
            {
                xml = (string) reader["Data"];
            }
            reader.Close();
            return WorkflowDesign.Read(xml);
        }

        public static WorkflowDesign GetWorkflowByName(string workflowName)
        {
            string workflowXml = null;
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            IDataReader reader = db.ExecuteReader("WorkflowGetByName", workflowName);
            Dictionary<Version,string> workflowData=new Dictionary<Version, string>();
            while (reader.Read())
            {
                string version = (string) reader["Version"];
                string xml = (string)reader["Data"];
                workflowData.Add(new Version(version), xml);
            }
            reader.Close();
            if (workflowData.Count > 0)
            {
                List<Version> versions = new List<Version>();
                versions.AddRange(workflowData.Keys);
                versions.Sort();
                workflowXml = workflowData[versions[versions.Count - 1]];
            }
            return WorkflowDesign.Read(workflowXml);
        }

        public static WorkflowDesign GetWorkflowByComponent(Guid componentID)
        {
            string workflowXml = null;
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            IDataReader reader = db.ExecuteReader("WorkflowGetByComponent", componentID);
            Dictionary<Version, string> workflowData = new Dictionary<Version, string>();
            while (reader.Read())
            {
                string version = (string)reader["Version"];
                string xml = (string)reader["Data"];
                workflowData.Add(new Version(version), xml);
            }
            reader.Close();
            if (workflowData.Count > 0)
            {
                List<Version> versions = new List<Version>();
                versions.AddRange(workflowData.Keys);
                versions.Sort();
                workflowXml = workflowData[versions[versions.Count - 1]];
            }
            return WorkflowDesign.Read(workflowXml);
        }

        public static WorkflowDesign GetWorkflowByRun(Guid runID)
        {
            string workflowXml = null;
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            IDataReader reader = db.ExecuteReader("WorkflowGetByRun", runID);
            Dictionary<Version, string> workflowData = new Dictionary<Version, string>();
            while (reader.Read())
            {
                string version = (string)reader["Version"];
                string xml = (string)reader["Data"];
                workflowData.Add(new Version(version), xml);
            }
            reader.Close();
            if (workflowData.Count > 0)
            {
                List<Version> versions = new List<Version>();
                versions.AddRange(workflowData.Keys);
                versions.Sort();
                workflowXml = workflowData[versions[versions.Count - 1]];
            }
            return WorkflowDesign.Read(workflowXml);
        }

        public static List<WorkflowDesign> GetAllWorkflows()
        {
            List<WorkflowDesign> wfDesigns=new List<WorkflowDesign>();
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            IDataReader reader = db.ExecuteReader("WorkflowGetAll");
            Dictionary<string, WorkflowDesign> workflowData = new Dictionary<string, WorkflowDesign>();
            while (reader.Read())
            {
                string workflowName = (string) reader["WorkflowName"];
                string versionName = (string)reader["Version"];
                Version version=new Version(versionName);
                string xml = (string)reader["Data"];
                if(workflowData.ContainsKey(workflowName))
                {
                    if (workflowData[workflowName].Version < version)
                        workflowData[workflowName] = WorkflowDesign.Read(xml);
                }
                else 
                    workflowData.Add(workflowName, WorkflowDesign.Read(xml));
            }
            reader.Close();
            wfDesigns.AddRange(workflowData.Values);
            return wfDesigns;
        }

        public static void SaveWorkflow(WorkflowDesign wfDesign)
        {
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            db.ExecuteNonQuery("SaveWorkflow",
                               wfDesign.WorkflowID,
                               wfDesign.WorkflowName,
                               wfDesign.FileName,
                               wfDesign.Version.ToString(),
                               wfDesign.Author,
                               wfDesign.CreatedOn,
                               wfDesign.ModifiedOn,
                               wfDesign.XmlData);
        }

        public static void SaveWorkflow(WorkflowDesign wfDesign, string xml)
        {
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            db.ExecuteNonQuery("SaveWorkflow",
                               wfDesign.WorkflowID,
                               wfDesign.WorkflowName,
                               wfDesign.FileName,
                               wfDesign.Version.ToString(),
                               wfDesign.Author,
                               wfDesign.CreatedOn,
                               wfDesign.ModifiedOn,
                               xml);
        }

        public static void PublishWorkflow(string xml)
        {
            WorkflowDesign wfDesign = WorkflowDesign.Read(xml);
            SaveWorkflow(wfDesign, xml);
        }

        public static List<string> ListWorkflowNames()
        {
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            IDataReader reader = db.ExecuteReader("ListWorkflowNames");
            List<string> workflowNames=new List<string>();
            while(reader.Read())
            {
                workflowNames.Add(reader.GetString(0));
            }
            reader.Close();
            return workflowNames;
        }

        public static void DeleteWorkflowByName(string workflowName)
        {
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            db.ExecuteNonQuery("WorkflowDeleteByName", workflowName);
        }

        public static void DeleteWorkflow(Guid workflowID)
        {
            Database db = DatabaseFactory.CreateDatabase("Workflow");
            db.ExecuteNonQuery("WorkflowDelete", workflowID);
        }
    }
}
